﻿'Copyright (c) Microsoft Corporation.  All rights reserved.


Imports Microsoft.VisualBasic
Imports System
Imports System.IO
Imports System.Reflection
Imports System.Windows.Forms
Imports Microsoft.WindowsAPICodePack.Shell
Imports Microsoft.WindowsAPICodePack.Shell.Taskbar
Imports Microsoft.Win32
Imports Microsoft.WindowsAPICodePack
Imports System.Diagnostics

Namespace TaskbarDemo
	''' <summary>
	''' A word about known/custom categories.  In order for an application
	''' to have known/custom categories, a file type must be registered with
	''' that application.  This demo provides two menu items that allows you
	''' to register and unregister .txt files with this demo. By default
	''' shell displays the 'Recent' category for an application with a
	''' registered file type.
	''' 
	''' An exception will be thrown if you try to add a shell item to
	''' 'Custom Category 1' before registering a file type with this demo
	''' application.
	''' 
	''' Also, once a file type has been registered with this demo, setting
	''' jumpList.KnownCategoryToDisplay = KnownCategoryType.Neither will have
	''' no effect until at least one custom category or user task has been
	''' added to the taskbar jump list.
	''' </summary>    
	Partial Public Class TaskbarDemoMainForm
		Inherits Form
		Private Const appId As String = "TaskbarDemo"
		Private Const progId As String = "TaskbarDemo"

		Private category1 As New CustomCategory("Custom Category 1")
		Private category2 As New CustomCategory("Custom Category 2")

		Private jumpList As JumpList

		Private executableFolder As String
		Private ReadOnly executablePath As String

		Private initializing As Boolean = False

		#Region "Form Initialize"

		Public Sub New()
			initializing = True

			InitializeComponent()

			' Set the application specific id
			Taskbar.AppId = appId

			' Retrieve the taskbar jump list
			jumpList = Taskbar.JumpList

			' Add custom categories
			jumpList.CustomCategories.Add(category1)
			jumpList.CustomCategories.Add(category2)

			' Default values for jump lists
			comboBoxKnownCategoryType.SelectedItem = "Recent"

			' Progress Bar
			For Each state As String In System.Enum.GetNames(GetType(TaskbarButtonProgressState))
				comboBoxProgressBarStates.Items.Add(state)
			Next state

			' Update UI
			UpdateStatusBar("Application ready...")

			' Save current folder and path of running executable
			executablePath = System.Reflection.Assembly.GetEntryAssembly().Location
			executableFolder = Path.GetDirectoryName(executablePath)

			' Sanity check - will avoid throwing exceptions if the file type is not registered.
			CheckFileRegistration()

			'
			comboBoxProgressBarStates.SelectedItem = "Normal"

			' Set our title if we were launched from the Taskbar
			Dim args() As String = Environment.GetCommandLineArgs()

			If args.Length > 2 AndAlso args(1) = "/doc" Then
				Dim fileName As String = String.Join(" ", args, 2, args.Length - 2)
				Me.Text = String.Format("{0} - Taskbar Demo", Path.GetFileName(fileName))
			Else
				Me.Text = "Taskbar Demo"
			End If

			initializing = False
		End Sub

		Private Sub CheckFileRegistration()
			Dim registered As Boolean = False

			Try
				Dim openWithKey As RegistryKey = Registry.ClassesRoot.OpenSubKey(Path.Combine(".txt", "OpenWithProgIds"))
				Dim value As String = TryCast(openWithKey.GetValue(progId, Nothing), String)

				If value Is Nothing Then
					registered = False
				Else
					registered = True
				End If
			Finally
				' Let the user know
				If (Not registered) Then
					Dim td As New TaskDialog()

					td.Text = "File type is not registered"
					td.InstructionText = "This demo application needs to register .txt files as associated files to properly execute the Taskbar related features."
					td.Icon = TaskDialogStandardIcon.Information
					td.Cancelable = True

					Dim button1 As New TaskDialogCommandLink("registerButton", "Register file type for this application", "Register .txt files with this application to run this demo application correctly.")

					' Show UAC sheild as this task requires elevation
					button1.ShowElevationIcon = True

					td.StandardButtons = TaskDialogStandardButtons.None
					td.Controls.Add(button1)

					Dim tdr As TaskDialogResult = td.Show()

					If tdr.CustomButtonClicked = "registerButton" Then
						registerFileTypeToolStripMenuItem_Click(Nothing, EventArgs.Empty)
					End If
				End If
			End Try
		End Sub

		#End Region

		#Region "File Registration Helpers"

		Private Sub registerFileTypeToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles registerFileTypeToolStripMenuItem1.Click, registerFileTypeToolStripMenuItem.Click
			RegistrationHelper.RegisterFileAssociations(progId, False, appId, executablePath & " /doc %1", ".txt")
		End Sub

		Private Sub unregisterFileTypeToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles unregisterFileTypeToolStripMenuItem1.Click, unregisterFileTypeToolStripMenuItem.Click
			RegistrationHelper.UnregisterFileAssociations(progId, False, appId, executablePath & " /doc %1", ".txt")
		End Sub

		#End Region

		#Region "Menu Open/Close"

		Private Sub openToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles openToolStripMenuItem1.Click, openToolStripMenuItem.Click
			Dim dialog As New CommonOpenFileDialog()
			dialog.Title = "Select a text document to load"
			dialog.Filters.Add(New CommonFileDialogFilter("Text files (*.txt)", "*.txt"))

			Dim result As CommonFileDialogResult = dialog.ShowDialog()

			If result.Canceled = False Then
				ReportUsage(dialog.FileName)
				Process.Start(executablePath, "/doc " & dialog.FileName)
			End If
		End Sub

		Private Sub saveToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles saveToolStripMenuItem1.Click, saveToolStripMenuItem.Click
			Dim dialog As New CommonSaveFileDialog()
			dialog.Title = "Select where to save your file"
			dialog.Filters.Add(New CommonFileDialogFilter("Text files (*.txt)", "*.txt"))

			Dim result As CommonFileDialogResult = dialog.ShowDialog()

			If result.Canceled = False Then
				ReportUsage(dialog.FileName)
			End If
		End Sub

		Private Sub ReportUsage(ByVal fileName As String)
			' Report file usage to shell.  Note: The dialog box automatically
			' reports usage to shell, but it's still recommeneded that the user
			' explicitly calls AddToRecent. Shell will automatically handle
			' duplicate additions.
			Taskbar.JumpList.AddToRecent(fileName)

			UpdateStatusBar("File added to recent documents")
		End Sub

		#End Region ';

		#Region "Known Categories"

		Private Sub comboBoxKnownCategoryType_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles comboBoxKnownCategoryType.SelectedIndexChanged
			Select Case TryCast(comboBoxKnownCategoryType.SelectedItem, String)
				Case "None"
					jumpList.KnownCategoryToDisplay = KnownCategoryType.Neither
				Case "Recent"
					jumpList.KnownCategoryToDisplay = KnownCategoryType.Recent
				Case "Frequent"
					jumpList.KnownCategoryToDisplay = KnownCategoryType.Frequent
			End Select
		End Sub

		#End Region

		#Region "Custom Categories"

		Private Sub buttonCategoryOneAddLink_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonCategoryOneAddLink.Click
			' Specify path for shell item
			Dim path As String = String.Format("{0}\test{1}.txt", executableFolder, category1.JumpListItems.Count)

			' Make sure this file exists
			EnsureFile(path)

			' Add shell item to custom category
			category1.JumpListItems.Add(New JumpListItem(path))

			' Update status
            UpdateStatusBar(System.IO.Path.GetFileName(path) + " added to 'Custom Category 1'")
		End Sub

		Private Sub buttonCategoryTwoAddLink_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonCategoryTwoAddLink.Click
			' Specify path for shell link
			Dim path As String = String.Format("{0}\test{1}.txt", executableFolder, category2.JumpListItems.Count)

			' Add jump list link to custom category
			category2.JumpListItems.Add(New JumpListLink With {.Title = String.Format("Custom Item - {0}", category2.JumpListItems.Count), .Path = path, .IconReference = New IconReference(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.System), "notepad.exe"), 0)})

			' Update status
            UpdateStatusBar(System.IO.Path.GetFileName(path) & " added to 'Custom Category 2'")
		End Sub

		Private Sub EnsureFile(ByVal path As String)
			If File.Exists(path) Then
				Return
			End If

			' Simply create an empty file with the specified path
			Dim fileStream As FileStream = File.Create(path)
			fileStream.Close()
		End Sub

		Private Sub buttonUserTasksAddTasks_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonUserTasksAddTasks.Click
			' Don't add additional tasks after tasks have already been added
			If jumpList.UserTasks.Count > 0 Then
				Return
			End If

			' Path to Windows system folder
			Dim systemFolder As String = Environment.GetFolderPath(Environment.SpecialFolder.System)

			' Add our user tasks
			jumpList.UserTasks.Add(New JumpListLink With {.Title = "Open Notepad", .Path = Path.Combine(systemFolder, "notepad.exe"), .IconReference = New IconReference(Path.Combine(systemFolder, "notepad.exe"), 0)})

			jumpList.UserTasks.Add(New JumpListLink With {.Title = "Open Paint", .Path = Path.Combine(systemFolder, "mspaint.exe"), .IconReference = New IconReference(Path.Combine(systemFolder, "mspaint.exe"), 0)})

			jumpList.UserTasks.Add(New JumpListSeparator())

			jumpList.UserTasks.Add(New JumpListLink With {.Title = "Open Calculator", .Path = Path.Combine(systemFolder, "calc.exe"), .IconReference = New IconReference(Path.Combine(systemFolder, "calc.exe"), 0)})

			' Update status
			UpdateStatusBar("Three user tasks added to jump list")
		End Sub

		Private Sub buttonCategoryOneRename_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonCategoryOneRename.Click
			category1.Name = "Updated Category Name"
		End Sub

		#End Region

		#Region "Progress Bar"

		Private Sub buttonProgressBarToggle_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonProgressBarToggle.Click
			If buttonProgressBarToggle.Text = "Start" Then
				' Start the progress bar timer
				timerProgressBar.Enabled = True
				buttonProgressBarToggle.Text = "Pause"

				' Reset the progress bar if necessary
				If progressBar1.Value >= progressBar1.Maximum Then
					progressBar1.Value = 0
				End If

				' resume the taskbar progressbar
				comboBoxProgressBarStates.SelectedItem = "Normal" ' this will trigger a call to UpdateProgressBar()
			Else
				' Stop the timer
				timerProgressBar.Enabled = False
				buttonProgressBarToggle.Text = "Start"

				' Pause the taskbar progressbar too
				comboBoxProgressBarStates.SelectedItem = "Paused" ' this will trigger a call to UpdateProgressBar()
			End If

			UpdateProgressBar()
		End Sub

		Private Sub timerProgressBar_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles timerProgressBar.Tick
			If Taskbar.ProgressBar.State = TaskbarButtonProgressState.Normal Then
				progressBar1.Style = ProgressBarStyle.Continuous

				progressBar1.PerformStep()

				' Turn off the progress bar timer if it's done
				If progressBar1.Value >= progressBar1.Maximum Then
					timerProgressBar.Enabled = False
					buttonProgressBarToggle.Text = "Start"
				End If

				UpdateProgressBar()
			Else
				' Skip increasing the value
				If Taskbar.ProgressBar.State = TaskbarButtonProgressState.Indeterminate Then
					progressBar1.Style = ProgressBarStyle.Marquee
				End If
			End If
		End Sub

		Private Sub comboBoxProgressStates_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) Handles comboBoxProgressBarStates.SelectedIndexChanged
			UpdateProgressBar()
		End Sub

		Private Sub UpdateProgressBar()
			If initializing Then
				Return
			End If

			Taskbar.ProgressBar.State = CType(System.Enum.Parse(GetType(TaskbarButtonProgressState), CStr(comboBoxProgressBarStates.SelectedItem)), TaskbarButtonProgressState)

			If Taskbar.ProgressBar.State <> TaskbarButtonProgressState.Indeterminate Then
				Taskbar.ProgressBar.CurrentValue = progressBar1.Value
			End If
		End Sub

		#End Region ';

		#Region "Icon Overlay"

		Private Sub labelNoIconOverlay_Click(ByVal sender As Object, ByVal e As EventArgs) Handles labelNoIconOverlay.Click
			Taskbar.OverlayImage = Nothing
		End Sub

		Private Sub pictureIconOverlay1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles pictureIconOverlay1.Click
			Taskbar.OverlayImage = New OverlayImage(My.Resources.Green, "Green")
		End Sub

		Private Sub pictureIconOverlay2_Click(ByVal sender As Object, ByVal e As EventArgs) Handles pictureIconOverlay2.Click
			Taskbar.OverlayImage = New OverlayImage(My.Resources.Yellow, "Yellow")
		End Sub

		Private Sub pictureIconOverlay3_Click(ByVal sender As Object, ByVal e As EventArgs) Handles pictureIconOverlay3.Click
			Taskbar.OverlayImage = New OverlayImage(My.Resources.Red, "Red")
		End Sub
		#End Region

		Private Sub UpdateStatusBar(ByVal status As String)
			toolStripStatusLabel1.Text = status
		End Sub

		Private Sub numericUpDownKnownCategoryLocation_ValueChanged(ByVal sender As Object, ByVal e As EventArgs) Handles numericUpDownKnownCategoryLocation.ValueChanged
			Taskbar.JumpList.KnownCategoryOrdinalPosition = Convert.ToInt32(numericUpDownKnownCategoryLocation.Value)
		End Sub

		Private Sub buttonRefreshTaskbarList_Click(ByVal sender As Object, ByVal e As EventArgs) Handles buttonRefreshTaskbarList.Click
			Taskbar.JumpList.RefreshTaskbarList()
		End Sub

		Private Sub newToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles newToolStripMenuItem.Click
			Dim childWindow As New ChildDocument()
			childWindow.Text = String.Format("Child Document Window ({0})", Me.MdiChildren.Length + 1)
			childWindow.Show()
		End Sub
	End Class
End Namespace